/*******************************************************************************
Program	: Back Propogation Neural Network.
Author  : 

*******************************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<math.h>

/****************************************************************************/
int 	inpNode,hidNode,outNode,epoc=0,iter=0;
long	i,t,j,k,fp=0,tp=0,tn=0,fn=0,modify;
long	cntTrnData=0,misTst=0,cntTstData=0,Misclsf = 0;
int	ch,misc=0,amaxInd,dmaxInd;
double 	**wih,**who,**pwih,**cwih,**pwho,**cwho,**trnData,**tstData;
double	*attenFun,*beta,*pbeta,**aoutput,*delta,*delta1,*delta_inp;
double	sse=0,prevsse=0,n=1.5;
double 	**err,**aoutput1,**aoutput2,*outdelta;
double	*netValHid,*hidActiv,*netValOup,**doutTrn,*outActiv,**doutTst,d;
FILE 	*fr,*fw;
char 	trainingfile[50],testingfile[60],statusfile[50],ihfile[50],hofile[50],*index;
time_t 	t;
double 	*iv;
char	ihfile[50],hofile[50];

/****************************************************************************/

void	training();
void 	testing();
void 	initialize();
void 	memory_free();
void 	Free(double ** , int );
void 	weight_initialization();
double	sigmoid(double );
double 	**memory2double(int ,int ,char * );
void initialize_from_file();
int module;

time_t t;

/******************************************************************************/
int main()
{
	
	
	FILE *temp,*out,*outtrain;
	
	
	printf("Want to initialize from file/random(1/0): ");
	scanf("%d",&module);
	
	if(!module)
	{
		printf("\n Enter the no of input nodes...");
		scanf("%d",&inpNode);
	
		printf("\n Enter the no of hidden nodes...");
		scanf("%d",&hidNode);
	
		printf("\n Enter the no of output nodes...");
		scanf("%d",&outNode);
	
	}
	printf("\n Enter the no of iterations...");
	scanf("%d",&iter);
	
	printf("\n Enter the name of the training file...");
	scanf("%s",trainingfile);	
	
	printf("\n Enter the name of the testing file...");
	scanf("%s",testingfile);
	
	printf("\n Enter the name of the status file...");
	scanf("%s",statusfile);
	
/*	printf("\nEnter the name of input-hidden weight file\n");
	scanf("%s",ihfile);
	
	printf("\nEnter the name of hidden-output weight file\n");
	scanf("%s",hofile);*/
	
	
	/**************   INITIALIZATION  *************/
	if(!module)
	{	
		temp=fopen(statusfile,"w");
		fclose(temp);
	
		out=fopen("output.txt","w");
		fclose(out);
		outtrain=fopen("outtrain.txt","w");	
		fclose(outtrain);	
	
		initialize();
	}
	
	if(module)
	{
		temp=fopen(statusfile,"a");
		fclose(temp);
		
		out=fopen("output.txt","w");
		fclose(out);
		outtrain=fopen("outtrain.txt","w");	
		fclose(outtrain); 
		
		
		printf("\nEnter the name of input-hidden weight file\n");
		scanf("%s",ihfile);
	
		printf("\nEnter the name of hidden-output weight file\n");
		scanf("%s",hofile);
	
		initialize_from_file();
	}
	
	training();	
	
	memory_free();
	
	return(0);	
}
/******************************************************************************/

void 	initialize()
{
	
	long seed;
	
	/***DYNAMIC MEMORY ALLOCATION FOR THE ARRAYS TO STORE THE WEIGHTS ***/
	
	wih = (double**)calloc(hidNode,sizeof(double*));
	cwih = (double**)calloc(hidNode,sizeof(double*));
	pwih = (double**)calloc(hidNode,sizeof(double*));
	if(wih == NULL)
	{
		printf("\n Error wih\n");
		exit(0);
	}
	for(i = 0 ;i < hidNode ; i++)
	{
		wih[i] = (double*)calloc(inpNode,sizeof(double));
		cwih[i] = (double*)calloc(inpNode,sizeof(double));
		pwih[i] = (double*)calloc(inpNode,sizeof(double));
		if(wih[i] == NULL)
		{
			printf("\n Error wih[%d]\n",i);
			exit(0);
		}
	}
	
	who = (double**)calloc(outNode,sizeof(double*));
	cwho = (double**)calloc(outNode,sizeof(double*));
	pwho = (double**)calloc(outNode,sizeof(double*));
	if(who == NULL)
	{
		printf("\n Error who\n");
		exit(0);
	}
	for(i = 0 ; i < outNode ; i++)
	{
		who[i] = (double*)calloc(hidNode,sizeof(double));
		cwho[i] = (double*)calloc(hidNode,sizeof(double));
		pwho[i] = (double*)calloc(hidNode,sizeof(double));
		if(who[i] == NULL)
		{
			printf("\n Error who[%d]\n",i);
			exit(0);
		}
	}
	
	
	/********DYNAMIC MEMORY ALLOCATION FOR THE ACTIVATION VALUES**********/
	
	netValHid = (double*)calloc(hidNode,sizeof(double));
	hidActiv = (double*)calloc(hidNode,sizeof(double));
	outdelta=(double*)calloc(outNode,sizeof(double));
	netValOup = (double*)calloc(outNode,sizeof(double));
	
	/*****DYNAMIC MEMORY ALLOCATION FOR STORING THE ATTENUATION VALUES*****/
	
	attenFun = (double*)calloc(inpNode,sizeof(double));
	beta = (double*)calloc(inpNode,sizeof(double));
	pbeta = (double*)calloc(inpNode,sizeof(double));	
	delta1 = (double*)calloc(hidNode,sizeof(double));
	delta = (double*)calloc(hidNode,sizeof(double));
	delta_inp =(double*)calloc(inpNode,sizeof(double));
	
	fr = fopen(trainingfile,"r");
	while(!feof(fr))
	{
		if((ch=getc(fr))=='\n')
			cntTrnData++;
			
	}
	fclose(fr);
	printf("\n training data = %d\n",cntTrnData);
	
	/********DYNAMIC MEMORY ALLOCATION FOR THE TRAINING DATA ARRAY********/
	
	trnData = (double**)calloc(cntTrnData,sizeof(double*));
	if(trnData == NULL)
	{
		printf("\n Error trnData\n");
	}
	for( long i = 0 ; i < cntTrnData ; i++)
	{
		trnData[i] = (double*)calloc((inpNode+outNode),sizeof(double));
		if(trnData[i] == NULL)
		{
			printf("\n Error trnData[%ld]",i);
		}
	}
	
	/*********READING THE TRAINING FILE**************/
	
	fr = fopen(trainingfile,"r");
	for(long i = 0 ; i < cntTrnData ; i++)
	{
		for(j = 0 ; j <(inpNode+outNode) ; j++)
		{				
			fscanf(fr,"%lf",&trnData[i][j]);					
		}
	}
	fclose(fr);	
		
	
	/*******DYNAMIC MEMORY ALLOCATION FOR THE DESIRED OUTPUT ARRAY*******/
	
	doutTrn = (double**)calloc(cntTrnData,sizeof(double*));
	if(doutTrn == NULL)
	{
		printf("\n Error doutTrn\n");
		exit(0);
	}
	for(i=0 ; i<cntTrnData ; i++)
	{
		doutTrn[i] = (double*)calloc(outNode,sizeof(double));
	}	
	for(i = 0 ; i < cntTrnData ; i++)
	{
		for(j=0 ; j<outNode; j++)
		{
			doutTrn[i][j] = trnData[i][inpNode+j];
			
		}	
	}
	
	aoutput = (double**)calloc(cntTrnData,sizeof(double*));
	aoutput1 = (double**)calloc(cntTrnData,sizeof(double*));
	err = (double**)calloc(cntTrnData,sizeof(double*));
	for(i=0 ; i<cntTrnData ; i++)
	{
		aoutput[i] = (double*)calloc(outNode,sizeof(double));
		aoutput1[i] = (double*)calloc(outNode,sizeof(double));
		err[i] = (double*)calloc(outNode,sizeof(double));
	}	
	
			
	/********** INITIALIZING THE WEIGHT OF THE NN ***********************/
	srand((unsigned)time(&t));
	
	/*seed = (long)time(NULL);
	srand48(seed);*/
	for(i = 0 ;i <hidNode ; i++)
	{
		for(j = 0 ; j <inpNode ; j++)
		{
			
			d=(double)rand()/32767;
			wih[i][j]=d-0.5;
			pwih[i][j] = wih[i][j];	
			printf("%9.4lf ",wih[i][j]);
		}
		printf("\n");
	}
	
	srand((unsigned)time(&t));
	
	for(i = 0 ; i < outNode ; i++)
	{
		for(j = 0 ; j < hidNode ; j++)
		{
			
			
			d=(double)rand()/32767;
			who[i][j]=d-0.5;
			pwho[i][j] = who[i][j];	
			
			printf("%9.4lf ",who[i][j]);
		}
		printf("\n");
	}
	
	
	
		
		
		cntTstData = 0;
		fr = fopen(testingfile,"r");
	
		while(!feof(fr))
		{
			if((ch=getc(fr))=='\n')
			cntTstData++;
			
		}
		fclose(fr);		
				
		
		printf("\n cnttstdata=%d\n",cntTstData);
		/********DYNAMIC MEMORY ALLOCATION FOR THE TESTING DATA ARRAY********/
	
		tstData = (double**)calloc(cntTstData,sizeof(double*));
		
		if(tstData == NULL)
		{
			printf("\n Error tstData\n");
		}
		for( i = 0 ; i < cntTstData ; i++)
		{
			tstData[i] = (double*)calloc((inpNode+outNode),sizeof(double));
			if(tstData[i] == NULL)
			{
			
				printf("\n Error tstData[%d]",i);
			}
		}
		/*********READING THE TESTING FILE**************/
	
		fr = fopen(testingfile,"r");
		for(i = 0 ; i < cntTstData ; i++)
		{
			for(j = 0 ; j <(inpNode+outNode) ; j++)
			{
				
				fscanf(fr,"%lf",&tstData[i][j]);
				
			
			}
		}
		fclose(fr);
		
		/********DYNAMIC MEMORY ALLOCATION FOR THE DESIRED OUTPUT ARRAY*******/
		printf("\n oupnode = %d\n",outNode);
		printf("\n inpnode = %d\n",inpNode);
		
		doutTst = (double**)calloc(cntTstData,sizeof(double*));
		if(doutTst == NULL)
		{
			printf("\n Error doutTst\n");
			exit(0);
		}
		
		for(i=0 ; i<cntTstData ; i++)
		{
			doutTst[i] = (double*)calloc(outNode,sizeof(double));
		}
		
		for(i = 0 ; i < cntTstData ; i++)
		{
			
			for(j=0 ; j<outNode; j++)
			{
				doutTst[i][j] = tstData[i][inpNode+j];
				
			}	
		}
		
		aoutput2 = (double**)calloc(cntTstData,sizeof(double*));
		for(i=0 ; i<cntTstData ; i++)
		{
			aoutput2[i] = (double*)calloc(outNode,sizeof(double));
			
		}
		
		
	
	return;		
	

}
/******************************************************************************/

/************************************************************************************************/
void initialize_from_file()
{
	FILE * fp,*fp1;
	
	fp=fopen(ihfile,"r");
	fp1=fopen(hofile,"r");
	
	fscanf(fp,"%d %d %lf",&inpNode,&hidNode,&n);
	fscanf(fp1,"%d %d %lf",&hidNode,&outNode,&n);
/**************************************SECTION COPIED**************************************************************/


	wih = (double**)calloc(hidNode,sizeof(double*));
	cwih = (double**)calloc(hidNode,sizeof(double*));
	pwih = (double**)calloc(hidNode,sizeof(double*));
	if(wih == NULL)
	{
		printf("\n Error wih\n");
		exit(0);
	}
	for(i = 0 ;i < hidNode ; i++)
	{
		wih[i] = (double*)calloc(inpNode,sizeof(double));
		cwih[i] = (double*)calloc(inpNode,sizeof(double));
		pwih[i] = (double*)calloc(inpNode,sizeof(double));
		if(wih[i] == NULL)
		{
			printf("\n Error wih[%d]\n",i);
			exit(0);
		}
	}
	
	who = (double**)calloc(outNode,sizeof(double*));
	cwho = (double**)calloc(outNode,sizeof(double*));
	pwho = (double**)calloc(outNode,sizeof(double*));
	if(who == NULL)
	{
		printf("\n Error who\n");
		exit(0);
	}
	for(i = 0 ; i < outNode ; i++)
	{
		who[i] = (double*)calloc(hidNode,sizeof(double));
		cwho[i] = (double*)calloc(hidNode,sizeof(double));
		pwho[i] = (double*)calloc(hidNode,sizeof(double));
		if(who[i] == NULL)
		{
			printf("\n Error who[%d]\n",i);
			exit(0);
		}
	}
	
	
	/********DYNAMIC MEMORY ALLOCATION FOR THE ACTIVATION VALUES**********/
	
	netValHid = (double*)calloc(hidNode,sizeof(double));
	hidActiv = (double*)calloc(hidNode,sizeof(double));
	outdelta=(double*)calloc(outNode,sizeof(double));
	netValOup = (double*)calloc(outNode,sizeof(double));
	
	/*****DYNAMIC MEMORY ALLOCATION FOR STORING THE ATTENUATION VALUES*****/
	
	attenFun = (double*)calloc(inpNode,sizeof(double));
	beta = (double*)calloc(inpNode,sizeof(double));
	pbeta = (double*)calloc(inpNode,sizeof(double));	
	delta1 = (double*)calloc(hidNode,sizeof(double));
	delta = (double*)calloc(hidNode,sizeof(double));
	delta_inp =(double*)calloc(inpNode,sizeof(double));
	
	fr = fopen(trainingfile,"r");
	while(!feof(fr))
	{
		if((ch=getc(fr))=='\n')
			cntTrnData++;
			
	}
	fclose(fr);
	printf("\n training data = %d\n",cntTrnData);
	
	/********DYNAMIC MEMORY ALLOCATION FOR THE TRAINING DATA ARRAY********/
	
	trnData = (double**)calloc(cntTrnData,sizeof(double*));
	if(trnData == NULL)
	{
		printf("\n Error trnData\n");
	}
	for( i = 0 ; i < cntTrnData ; i++)
	{
		trnData[i] = (double*)calloc((inpNode+outNode),sizeof(double));
		if(trnData[i] == NULL)
		{
			printf("\n Error trnData[%d]",i);
		}
	}
	
	/*********READING THE TRAINING FILE**************/
	
	fr = fopen(trainingfile,"r");
	for(i = 0 ; i < cntTrnData ; i++)
	{
		for(j = 0 ; j <(inpNode+outNode) ; j++)
		{				
			fscanf(fr,"%lf",&trnData[i][j]);					
		}
	}
	fclose(fr);	
		
	
	/*******DYNAMIC MEMORY ALLOCATION FOR THE DESIRED OUTPUT ARRAY*******/
	
	doutTrn = (double**)calloc(cntTrnData,sizeof(double*));
	if(doutTrn == NULL)
	{
		printf("\n Error doutTrn\n");
		exit(0);
	}
	for(i=0 ; i<cntTrnData ; i++)
	{
		doutTrn[i] = (double*)calloc(outNode,sizeof(double));
	}	
	for(i = 0 ; i < cntTrnData ; i++)
	{
		for(j=0 ; j<outNode; j++)
		{
			doutTrn[i][j] = trnData[i][inpNode+j];
			
		}	
	}
	
	aoutput = (double**)calloc(cntTrnData,sizeof(double*));
	aoutput1 = (double**)calloc(cntTrnData,sizeof(double*));
	err = (double**)calloc(cntTrnData,sizeof(double*));
	for(i=0 ; i<cntTrnData ; i++)
	{
		aoutput[i] = (double*)calloc(outNode,sizeof(double));
		aoutput1[i] = (double*)calloc(outNode,sizeof(double));
		err[i] = (double*)calloc(outNode,sizeof(double));
	}	
	
/******************************************************************************************************************/
	
	
	
	for(int i=0;i<hidNode;i++)
	{
		for(int j=0;j<inpNode;j++)
		{
			fscanf(fp,"%lf",&wih[i][j]);
		}
	}
	fclose(fp);
	
	
	for(int i=0;i<outNode;i++)
	{
		for(int j=0;j<hidNode;j++)
		{
			fscanf(fp1,"%lf",&who[i][j]);
		}
	}
	
	fclose(fp1);
}

/*************************************************************************************************/

/******************************************************************************/


double **memory2double(int a,int b,char *s)
{
	double **temp;
	int i;
	
	temp = (double**)calloc(a,sizeof(double*));
	
	if(temp == NULL)
	{
		printf("\n Error %s\n",s);
		exit(0);
	}
	for(i = 0; i < a; i++)
	{
		temp[i] = (double*)calloc(b,sizeof(double));
		if(temp[i] == NULL)
		{
			printf("\n Error %s[%d]\n",s,i);
			exit(0);
		}
	}
	
	return(temp);
}


/******************************************************************************/
double sigmoid(double x)
{
	double sig;
	double d;
	d=exp(-x);
	d=d+1;
	sig = (double)(1/d);
	return(sig);
}
/******************************************************************************/
void training()
{
	
	FILE	*fp1,*fp2,*fp3;
	long i,j,k;
	char	name1[50],name2[50],name3[50],*index;
	
	
	/********DYNAMIC MEMORY ALLOCATION FOR THE DESIRED OUTPUT ARRAY*******/
	doutTrn = memory2double(cntTrnData,outNode,"doutTrn");
	aoutput = memory2double(cntTrnData,outNode,"aoutput");
	aoutput1= memory2double(cntTrnData,outNode,"aoutput1");
	
	
	/********DYNAMIC MEMORY ALLOCATION FOR THE ACTIVATION VALUES**********/
	
	netValHid = (double*)calloc(hidNode,sizeof(double));
	hidActiv = (double*)calloc(hidNode,sizeof(double));	
	netValOup = (double*)calloc(outNode,sizeof(double));
	outActiv=(double*)calloc(outNode,sizeof(double));
	
	for(i = 0 ; i < cntTrnData ; i++)
	{
		for(j=0 ; j<outNode; j++)
		{
			doutTrn[i][j] = trnData[i][inpNode+j];			
		}	
	}
	iv=(double*)malloc(inpNode*sizeof(double));	
	epoc = 0;
	
  	 while(epoc<iter)
   	{	
	

		for(int k=0;k<cntTrnData;k++)
		{
			for(i=0;i<inpNode;i++)
				iv[i]=trnData[k][i];
	
	
	/****************************************HIDDEN ACTIVATION CALC*****************************/
			for(i=0;i<hidNode;i++)
			{	
				netValHid[i]=0;
				for(j=0;j<inpNode;j++)
					netValHid[i]+=iv[j]*wih[i][j];
				hidActiv[i]=sigmoid(netValHid[i]);
			}
	/*********************************************************************************************/
	
	/************************************OUTPUT CALC*********************************************************/
	
			for(i=0;i<outNode;i++)
			{	
				netValOup[i]=0;
				for(j=0;j<hidNode;j++)
					netValOup[i]+=hidActiv[j]*who[i][j];
				outActiv[i]=sigmoid(netValOup[i]);
			}
		
	/*********************************************************************************************/
	
	
	/*****************************************OUTPUT ERROR CALC****************************************************/
	
			for(i=0;i<outNode;i++)
			{
				err[k][i]=0;
				err[k][i]=(doutTrn[k][i]-outActiv[i]);
			}	
	
	/*********************************************************************************************/
	
	
	/****************************************OUTPUT LAYER DELTA*****************************************************/
		
			for(i=0;i<outNode;i++)
			{
			
				outdelta[i]=err[k][i]*outActiv[i]*(1-outActiv[i]);
		
			}
	/*********************************************************************************************/
	
	
	/******************************HIDDEN TO OUTPUT DEL WEIGHT***************************************************************/
	
			for(i=0;i<outNode;i++)
				for(j=0;j<hidNode;j++)
		  		 	cwho[i][j]=n*outdelta[i]*hidActiv[j];
	
	/*********************************************************************************************/
	
	
	/****************************HIDDEN LAYER DELTA CALC*****************************************************************/
	
	
			for(i=0;i<hidNode;i++)
			{
				delta[i]=0.0;
			}
		
		
			for(i=0;i<hidNode;i++)
			{
				for(j=0;j<outNode;j++)
				{
					delta[i]+=outdelta[j]*who[j][i];
				}
				delta[i]=delta[i]*hidActiv[i]*(1-hidActiv[i]);
			
			}
	
	/**********************************************************************************************************/
	
	
	/************************************INPUT TO HIDDEN DEL WEIGHT**********************************************************************/
	
			for(i=0;i<hidNode;i++)
			{
				for(j=0;j<inpNode;j++)
				{
					cwih[i][j]=n*delta[i]*iv[j];
				}
			}
	
	
	/**********************************************************************************************************/
	
	
	
	
	
	
	/*******************************************UPDATION OF WHO***************************************************************/
	
		
			
			for(i=0;i<outNode;i++)
			{
				for(j=0;j<hidNode;j++)
				{
					who[i][j]=who[i][j]+cwho[i][j];
				}
			}
		
	
	/**********************************************************************************************************/
	
	
	/********************************************UPDATION OF WIH**************************************************************/
	
			for(i=0;i<hidNode;i++)
			{
				for(j=0;j<inpNode;j++)
				{
					wih[i][j]=wih[i][j]+cwih[i][j];
				}
			}
	
	
	/**********************************************************************************************************/
	
		}
		
			
		Misclsf = 0;
		sse = 0;
		fp = 0;
		fn = 0;								
		
		for(k = 0 ; k < cntTrnData ; k++)
		{
			for(i = 0 ; i < hidNode ; i++)
			{
				netValHid[i] = hidActiv[i] = 0;
				for(j = 0 ; j < inpNode ; j++)
				{
					netValHid[i] += (wih[i][j]*trnData[k][j]);
				}
			}
			
			for(i = 0 ; i < hidNode ; i++)
			{
				hidActiv[i] = sigmoid(netValHid[i]);
			}
			
							
			for(i = 0 ; i < outNode ; i++)
			{
				netValOup[i] = aoutput1[k][i] = 0;
				for(j = 0 ; j < hidNode ; j++)
				{
					netValOup[i] += (who[i][j] * hidActiv[j]);
				}
			}
			for(i = 0;i<outNode ;i++)
			{				
				aoutput1[k][i] = sigmoid(netValOup[i]);
				
				
			}
			for(i=0 ; i<outNode ;i++)
			{	
				err[k][i] = doutTrn[k][i] - aoutput1[k][i];
				sse+= err[k][i] * err[k][i];
			}	
			
			
			if(epoc == 0 )
			{
				for(i=0 ; i<outNode ;i++)
				{
					prevsse+= err[k][i] * err[k][i];
				}									
			}	
			amaxInd = 0;
			dmaxInd = 0;
			for(i=0 ; i<(outNode-1) ;i++)
			{
				if((aoutput1[k][amaxInd])<aoutput1[k][i+1])
			/*	if((aoutput1[k][amaxInd])< 0.4)*/
				{
					amaxInd = i+1;
				}
				
				if(doutTrn[k][dmaxInd]<doutTrn[k][i+1])
				{
					dmaxInd = i+1;
				}
				
			}	
			
			if(amaxInd!=dmaxInd)
			{
				Misclsf++;
				if(amaxInd < dmaxInd)
				{
					fn++;
				}
				else
					fp++;
			}
			
			
			/*************************WRITETRAININGOUTPUT**********************************/
		
		
			FILE *outtrain;
			outtrain=fopen("outtrain.txt","a");
			fprintf(outtrain,"%16.15lf  %16.15lf\n",aoutput1[k][0],aoutput1[k][1]);
			fclose(outtrain);
		/*******************************************************************************/			
		}
		
		FILE *fstatus;
		if((epoc % 50) == 0)
		{
			printf("\n Epoch = %d ",epoc);
			printf("\n Sum square error = %lf",sse);
			printf("\n Misclassification = %d (%d + %d)",Misclsf,fp,fn);
			printf("\n Learning parameter = %lf",n);
			
			fstatus=fopen(statusfile,"a");
			fprintf(fstatus,"%8d  %8d (%d + %d)  ",epoc,Misclsf,fp,fn);
			fclose(fstatus);
			
			testing();	
			
			
			char * str, file_i_h[20]="wih",file_h_o[20]="who";
			char *index;
			int index1=0;
			
			FILE *fih,*fho,*fstatus;
			
			
			int m=1,index_str=0;
			
			index1=epoc/50;
			str=(char*)malloc(sizeof(char));
			while(index1!=0)
			{
				
				m=index1%10;
				index1=index1/10;
				
				str[index_str]=m+48;
				index_str++;
				str=(char*)realloc(str,(index_str+1)*sizeof(char));
				
			}
			str[index_str]='\0';
			
			int len,forward=0,backward;
			len=strlen(str);
						
			index=(char*)malloc((len+1)*sizeof(char));
			for(backward=len-1;backward>=0;backward--)
			{
				index[forward]=str[backward];
				++forward;
			}
			index[forward]='\0';	
			
			/**********Weight Storage**************/
		
			/**********wih****************/
		
			strcat(file_i_h,index);
			strcat(file_h_o,index);
		
			fih=fopen(file_i_h,"w");
		
		
			fprintf(fih,"%d %d %16.15lf\n",inpNode,hidNode,n);
		
			for(int i=0;i<hidNode;i++)
			{	
				for(j=0;j<inpNode-1;j++)
				{
					fprintf(fih,"%16.15lf  ",wih[i][j]);
				}		
				fprintf(fih,"%16.15lf",wih[i][j]);
				fprintf(fih,"\n");
			}
		
			fclose(fih);
		
			fho=fopen(file_h_o,"w");
		
			fprintf(fho,"%d %d %16.15lf\n",hidNode,outNode,n);
		
			for(int i=0;i<outNode;i++)
			{	
				for(j=0;j<hidNode-1;j++)
				{
					fprintf(fho,"%16.15lf  ",who[i][j]);
				}		
				fprintf(fho,"%16.15lf",who[i][j]);
				fprintf(fho,"\n");
			}
			fclose(fho);	
		
			
			fstatus=fopen(statusfile,"a");
			fprintf(fstatus,"%8d(%8d + %8d) %016.8lf %016.8lf\n",misTst,fp,fn,n,sse);
			fclose(fstatus);		
			
			
		}
		
		if(sse > prevsse)
		{
			
			for(i = 0 ; i < hidNode ; i++)
			{
				for(j = 0 ;j < inpNode ; j++)
				{
					wih[i][j] = pwih[i][j];
					
				}
			}
			
			for(i = 0 ;i < outNode ; i++)
			{
				for(j = 0 ; j < hidNode ; j++)
				{
					who[i][j] = pwho[i][j];
				}
			}
									
			
			n=0.99*n;
			/*modify++;
			if(modify>5)
			{
				modify=0;
				if(n<0.01)
					n=0.9;
			}*/
				
			prevsse = prevsse;
			
		}
		else /*if(sse <= prevsse)*/
		{
			prevsse = sse;
			for(i = 0 ; i < outNode ; i++)
			{
				for(j = 0 ;j < hidNode ; j++)
				{
					pwho[i][j] = who[i][j];
				}
			}
			for(i = 0 ;i < hidNode ; i++)
			{
				for(j = 0 ; j < inpNode ; j++)
				{
					pwih[i][j] = wih[i][j];
				}
			}
			
		}	
											
		epoc++;
		
	}

	return;	
}

void testing()
{
	
	long i,j,k;
	
	misTst = 0;
	fp=0;
	tp=0;
	tn=0;
	fn=0;
		
	for( k = 0 ; k <cntTstData ; k++)
	{
	
		for(i = 0 ; i <hidNode ; i++)
		{
			netValHid[i] = hidActiv[i] = 0;
			for(j = 0 ; j < inpNode ; j++)
			{
				netValHid[i]+= (wih[i][j] * tstData[k][j]);
			}
		}
		
		for(i = 0 ; i < hidNode ; i++)
		{
			hidActiv[i] = sigmoid(netValHid[i]);
		}
			
		for(i = 0 ; i < outNode ; i++)
		{
			netValOup[i] = 0;
			aoutput2[k][i] = 0;
			for(j = 0 ; j < hidNode ; j++)
			{
				netValOup[i]+= (who[i][j] * hidActiv[j]);
			}
		}
			
		for(i = 0 ;i< outNode ; i++)
		{
			aoutput2[k][i] = sigmoid(netValOup[i]);
			
		}
			
						
		amaxInd = 0;
		dmaxInd = 0;
		
		if((aoutput2[k][0])<aoutput2[k][1])
		{
			amaxInd = 1;
		}
				
		if(doutTst[k][0]<doutTst[k][1])
		{
			dmaxInd = 1;
		}
					
			
		/***************************************OUPT^PUTWRITEFILE*******************/
			
		FILE * fout;
		fout=fopen("output.txt","a");
		fprintf(fout,"%16.15lf  %16.15lf  %16.15lf\n",netValOup[0],aoutput2[k][0],aoutput2[k][1]);
		fclose(fout);
			
		/****************************************************************************/
	
		if(amaxInd!=dmaxInd)
		{
			misTst++;
		}
		if((amaxInd == 0) && (dmaxInd == 1))
		{
			fp++;
		}
		if((amaxInd == 0) && (dmaxInd == 0))
		{
			tp++;
		}
		if((amaxInd == 1) && (dmaxInd == 0))		
		{
			fn++;
		}
		if((amaxInd == 1) && (dmaxInd == 1))
		{
			tn++;
		}				
		
	}
	printf("\n The testing misclassification....%d",misTst);
	printf("\n The pixels negative but giving positive...%ld",fp);
	printf("\n The pixels positive and giving positive...%ld",tp);
	printf("\n The pixels positive but giving negative...%ld",fn);
	printf("\n The pixels negative and giving negative...%ld\n",tn);
		
	return;			
			
	
}	

/******************************************************************************/
void memory_free()
{
	Free(wih,hidNode);
	Free(cwih,hidNode);
	Free(pwih,hidNode);
	Free(who,outNode);
	Free(cwho,outNode);
	Free(pwho,outNode);	
	
	Free(trnData,cntTrnData);
	Free(doutTrn,cntTrnData);
	Free(tstData,cntTstData);
	Free(doutTst,cntTstData);
	Free(aoutput,cntTrnData);
	Free(aoutput1,cntTrnData);
	Free(aoutput2,cntTstData);
	Free(err,cntTrnData);
	
	free(netValHid);
	free(hidActiv);
	free(netValOup);
	free(attenFun);	
	free(delta1);
	free(delta);
	free(delta_inp);
	free(outdelta);
	free(beta);
	free(pbeta);
		
	return;
	
}	


/******************************************************************************/
void Free(double **node, int a)
{
	int i;
	
	for(i=0;i<a;i++)
		free(node[i]);
	
	free(node);
	return;
}
/******************************************************************************/
/******************************************************************************/
